<template>
  <div class="yearpicker">
    <div class="yearpicker-header">
      <q-btn
        @click="changeYears(false)"
        dense
        :disable="minClean && minClean.getFullYear() === selectedYear.getFullYear()"
        flat
        icon="navigate_before"
        round
      />
      {{ yearRange }}
      <q-btn
        @click="changeYears(true)"
        dense
        :disable="maxClean && maxClean.getFullYear() === selectedYear.getFullYear()"
        flat
        icon="navigate_next"
        round
      />
    </div>
    <q-separator />
    <div class="yearpicker-years">
      <q-btn
        :class="{ 'yearpicker-current': isCurrentYear(year) }"
        @click="selectYear(year)"
        :color="isSelectedYear(year) ? color : ''"
        :disable="isDisabled(year)"
        :flat="!isSelectedYear(year)"
        :key="year.getTime()"
        :label="year.toLocaleDateString(localeArray, {
          year: 'numeric',
        })"
        no-caps
        no-outline
        no-ripple
        rounded
        :text-color="isCurrentYear(year) && !isSelectedYear(year) ? color : ''"
        v-for="year in displayedYears"
      />
    </div>
  </div>
</template>

<script>
import { defineComponent } from 'vue';
export default defineComponent({
  name: 'YearPicker',
  emits: ['input', 'change'],
  data () {
    return {
      selectedYear: null,
      beginYear: new Date()
    }
  },
  computed: {
    displayedYears () {
      const years = [];
      const beginYear = ~~(this.beginYear.getFullYear() / 10) * 10;

      for (let i = 0; i < 10; i++) {
        years.push(new Date(beginYear + i, 0));
      }

      return years;
    },
    yearRange () {
      const beginYear = ~~(this.beginYear.getFullYear() / 10) * 10;
      return `${beginYear} - ${beginYear + 9}`;
    },
    localeArray () {
      return this.locale ? [this.locale] : [];
    },
    maxClean () {
      return this.max ? this.cleanDate(this.max) : null;
    },
    minClean () {
      return this.min ? this.cleanDate(this.min) : null;
    }
  },
  methods: {
    changeYears (up) {
      if (up) {
        let d = new Date(this.beginYear);
        d.setFullYear(d.getFullYear() + 10);

        if (this.maxClean && d > this.maxClean) {
          d = this.maxClean;
        }
        this.beginYear = d;
      } else {
        let d = new Date(this.beginYear);
        d.setFullYear(d.getFullYear() - 10);

        if (this.minClean && d < this.minClean) {
          d = this.minClean;
        }
        this.beginYear = d;
      }
    },
    cleanDate (date) {
      if (date && String(date).length === 4) { // 2020这格式
        date = `${date}/01/01`;
      }
      const d = date ? new Date(date) : new Date();
      d.setDate(1);
      d.setHours(0, 0, 0, 0);
      return d;
    },
    currentYear () {
      return this.cleanDate();
    },
    isCurrentYear (year) {
      return this.currentYear().getTime() === year.getTime();
    },
    isDisabled (year) {
      let disabled = false;

      if ((this.minClean && year < this.minClean) || (this.maxClean && year > this.maxClean)) {
        disabled = true;
      }

      return disabled;
    },
    isSelectedYear (year) {
      return this.selectedYear
        ? (this.selectedYear.getTime() === year.getTime())
        : false;
    },
    selectYear (year) {
      this.selectedYear = year;

      this.$emit('input', `${year.getFullYear()}`);
      this.$emit('change', `${year.getFullYear()}`);
    }
  },
  props: [
    'color',
    'locale',
    'max',
    'min',
    'value'
  ],
  watch: {
    value: {
      handler (val) {
        this.selectedYear = val
          ? this.cleanDate(val)
          : this.currentYear()
      },
      immediate: true
    }
  }
});
</script>

<style>

.yearpicker {
  width: 300px;
  padding: 10px;
}

.yearpicker-current {
  font-weight: bold;
}

.yearpicker-header {
  align-items: center;
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
}

.yearpicker-years {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  margin-top: 5px;
}

.yearpicker-years .q-btn {
  box-shadow: none;
  margin: 4px 0;
  width: 30%;
}

</style>
